// 取消axios请求
import { AxiosRequestConfig } from 'axios';
import qs from 'qs';

// 生成唯一的id
const generatePendingId = (config: AxiosRequestConfig) => {
  // 根据 url + method + data/params 生成唯一id
  const { method, url, data, params } = config;
  let usefulData = data || params;
  // 对于data是字符串的情况，防止编码不一致，需要进行反序列化
  if (typeof usefulData === 'string') usefulData = JSON.parse(data);
  return [url as string, method, qs.stringify(usefulData)].join('&');
};

class AxiosCancelToken {
  private pendingQueue: Map<string, AbortController> = new Map(); // 请求队列

  pendingHandler(config: AxiosRequestConfig) {
    const key = generatePendingId(config);
    const controller = new AbortController();
    config.signal = controller.signal;
    if (this.pendingQueue.has(key)) {
      // 后入队的重复请求，会直接被取消
      controller.abort();
    } else {
      this.pendingQueue.set(key, controller);
    }
  }

  // 取消全部请求
  cancelAllPending() {
    this.pendingQueue.forEach(controller => {
      controller?.abort();
    });
    this.pendingQueue.clear();
  }

  // 删除请求
  removePending(config: AxiosRequestConfig) {
    const key = generatePendingId(config);
    this.pendingQueue.delete(key);
  }
}

export default new AxiosCancelToken();
